#include <iostream>
#include <cstdio>
#include <vector>
#include <functional>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        sleep(2);
        printf("Ciallo~\n");
        printf("Ciallo~\n");
        printf("Ciallo~\n");
        printf("Ciallo~\n");
        printf("Ciallo~\n");
        int a = 10;
        a /= 0;
        printf("Ciallo~\n");
        printf("Ciallo~\n");
        exit(1);
    }
    int status = 0;
    waitpid(id, &status, 0);
    printf("signal: %d, exitcode: %d, core dump: %d\n", (status&0x7F), (status>>8)&0xFF, (status>>7)&0x1); 
    return 0;
}


#if 0
void PrintPending(sigset_t pending)
{
    printf("我是一个进程( %d ), pending: ", getpid());
    for (int signo = 31; signo >= 1; signo--)
    {
        if (sigismember(&pending, signo))
        {
            std::cout << "1";
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << std::endl;
}

void handler(int sig)
{
    std::cout << "#######################################" << std::endl;
    std::cout << "递达" << sig << "信号 ~"<< std::endl;
    sigset_t pending;
    int m = sigpending(&pending);
    PrintPending(pending);
    // 若是0000 0010 处理完2号才置0
    // 若是0000 0000 处理前2号就置0
    std::cout << "#######################################" << std::endl;
}

int main()
{
    signal(SIGINT, handler);
    // 1. 屏蔽2号信号, block信号集2号位置1
    sigset_t block, oldblock;
    sigemptyset(&block);
    sigemptyset(&oldblock);
    sigaddset(&block, SIGINT); // 到此只改了变量, 需要更新到进程中

    // for (int i = 0; i <= 31; i++) // 会屏蔽所有信号， 除9外
    // {
    //     sigaddset(&block, i);
    // }
    int n = sigprocmask(SIG_SETMASK, &block, &oldblock);
    (void)n;

    // 4. 重复获取打印
    int cnt = 0;
    while (true)
    {
        // 2. 获取pending信号集
        sigset_t pending;
        int m = sigpending(&pending);
        // 3. 打印
        PrintPending(pending);
        if (cnt == 10)
        {
            // 5. 恢复对2号信号的阻塞, 会直接递达2号信号
            // 若不对2号信号做处理, 就会按默认直接终止进程
            std::cout << "解除对2号信号的屏蔽" << std::endl;
            sigprocmask(SIG_SETMASK, &oldblock, nullptr);
        }
        sleep(1);
        cnt++;
    }
    return 0;
}

#endif







#if 0
void handerSig(int sig)
{
    std::cout << "Ciallo~ Sig: " << sig << std::endl;
    signal(2, SIG_DFL);
    std::cout << "恢复处理动作" << std::endl;
}
int main()
{
    signal(2, handerSig);
    //signal(2, SIG_IGN);
    while (true)
    {
        sleep(1);
        std::cout << "." << std::endl;
    }
    return 0;
}
#endif

#if 0

struct task_struct
{
    pid_t id;
    int count = 10; // 时间片，本质也是计数器
    void(*code)();

};

////////////////////func///////////////////////////////
void Sched()
{
    std::cout << "进程调度" << std::endl;
}
void MemManger()
{
    std::cout << "内存管理" << std::endl;
}
void Fflush()
{
    std::cout << "刷新程序" << std::endl;
}
///////////////////////////////////////////////////////
using func_t = std::function<void()>; // 返回值为void的函数 命名为func_t类型
std::vector<func_t> funcs; // 返回值为void的函数列表

int timestamp = 0; // 时间戳

// 每隔一秒,完成一些任务
void handerSig(int sig) //会把signal函数的第一个参数传过来
{
    timestamp++; // 时间戳++
    std::cout << "##############################################" << std::endl;
    for (auto f : funcs) // 执行函数列表内的函数
    {
        f();
    }
    std::cout << "##############################################" << std::endl;
    int n = alarm(1); // 重新设定一个闹钟，成为循环
}
int main()
{
    funcs.push_back(Sched);
    funcs.push_back(MemManger);
    funcs.push_back(Fflush);
    // 遇到SIGALRM信号，执行handerSig，handerSig中又会设置下一个闹钟
    signal(SIGALRM, handerSig); 
    alarm(1); // 初始闹钟
    while (true)
    {
        // 进程一直暂停，一旦收到一个信号，唤醒一次
        pause();
    }
    return 0;
}

#endif

// void handerSig(int sig)//会把signal函数的第一个参数传过来
// {
//     std::cout << "获得了一个信号: " << sig << " pid: " << getpid() << std::endl;
//     alarm(1);
// }
// int main()
// {
//     signal(SIGALRM, handerSig);
//     alarm(1);

//     while (true)
//     {
//         // 进程暂停，一旦收到一个信号，唤醒一次
//         std::cout << ". " << getpid() << std::endl;
//         // sleep(1);
//         pause();
//     }
//     return 0;
// }

// int cnt = 0;
// void handerSig(int sig)//会把signal函数的第一个参数传过来
// {
//     std::cout << "获得了一个信号: " << sig << "cnt: " << cnt << std::endl;
//     exit(13);
// }

// int main()
// {
//     // for (int i = 0; i <= 32; i++)
//     //     signal(i, handerSig);
//     signal(SIGALRM, handerSig);
//     alarm(1);//闹钟1秒后响

//     while (true)
//     {
//         //std::cout << "count: " << cnt++ << std::endl; // 打印效率低
//         cnt++;
//     }
//     return 0;
// }